package club.yuit.desktop.ui.topics.cut;

import club.yuit.desktop.ui.topics.cut.TableBroker;
import club.yuit.rmq.model.BrokerDetails;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import club.yuit.desktop.ui.topics.cut.CUTTableHeaderCellRenderer;

/**
 * @author: yuit
 * @date: 2023/12/12 23:40
 */
@Slf4j
public class CUTopicBrokerTableModel extends AbstractTableModel {

    private Map<String, List<BrokerDetails>> brokers;
    private final List<TableBroker> data = new ArrayList<>();
    private String[] columnNames = new String[]{"选择", "名称"};

    private JTable table;


    public CUTopicBrokerTableModel(Map<String, List<BrokerDetails>> brokers, JTable table) {
        this.brokers = brokers;
        this.table = table;
        filterData(null);
    }

    public void filterData(String cluster) {
        if (!brokers.isEmpty()) {
            data.clear();
            for (Map.Entry<String, List<BrokerDetails>> entry : brokers.entrySet()) {
                if (cluster != null && !cluster.equals(entry.getKey())) {
                    continue;
                }
                List<BrokerDetails> v = entry.getValue();
                v.forEach(brokerDetails -> {
                    // 只有master 节点才能操作 topic
                    if (brokerDetails.getId() == 0) {
                        TableBroker tableBroker = new TableBroker();
                        try {
                            BeanUtils.copyProperties(tableBroker, brokerDetails);
                            tableBroker.setSelected(false);
                            data.add(tableBroker);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException(e);
                        }

                    }
                });
            }
        }
    }


    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }


    @Override
    public boolean isCellEditable(int row, int column) {
        return true;
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        TableBroker tableBroker = this.data.get(rowIndex);
        if (columnIndex == 0) {
            if (aValue instanceof Boolean) {
                tableBroker.setSelected((Boolean) aValue);
            }

            changeTitleBoxState();
            return;
        }
        if (aValue instanceof String) {
            tableBroker.setName((String) aValue);
        }

    }


    private void changeTitleBoxState() {
        long count = this.data.stream().filter(TableBroker::isSelected).count();
        JTableHeader tableHeader = table.getTableHeader();
        if (!data.isEmpty()) {
            if (count == 0) {
                CUTTableHeaderCellRenderer.CHECK_BOX.setChecked(false);
            } else if (count == data.size()) {
                CUTTableHeaderCellRenderer.CHECK_BOX.setChecked(true);
            } else {
                CUTTableHeaderCellRenderer.CHECK_BOX.setChecked(null);
            }

            tableHeader.updateUI();
        }

    }


    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return columnIndex == 0 ? Boolean.class : String.class;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex == 0) {
            return data.get(rowIndex).isSelected();
        }
        return data.get(rowIndex).getName();
    }

    public void allRowSelected(boolean selected) {

        log.debug("change select all status: {}", selected);

        for (TableBroker t : data) {
            t.setSelected(selected);
        }

        // 刷新表格
        fireTableChanged(new TableModelEvent(this));

    }


    public void clearSelected() {
        for (TableBroker t : data) {
            t.setSelected(false);
        }

        // 刷新表格
        fireTableChanged(new TableModelEvent(this));
        CUTTableHeaderCellRenderer.CHECK_BOX.setChecked(false);
        table.getTableHeader().updateUI();

    }


    public List<String> getSelectedBrokers() {
        return data.stream().filter(TableBroker::isSelected)
                .map(TableBroker::getName).collect(Collectors.toList());
    }


}
